package com.mh.service;

import com.mh.dao.CustomerDAO;
import com.mh.dao.InvoiceDAO;
import com.mh.dao.ItemDAO;

import com.mh.domain.Customer;
import com.mh.domain.Invoice;
import com.mh.domain.Item;

import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

/**
 * Spring service that handles CRUD requests for Invoice entities
 * 
 */

@Service("InvoiceService")
@Transactional
public class InvoiceServiceImpl implements InvoiceService {

	/**
	 * DAO injected by Spring that manages Customer entities
	 * 
	 */
	@Autowired
	private CustomerDAO customerDAO;

	/**
	 * DAO injected by Spring that manages Invoice entities
	 * 
	 */
	@Autowired
	private InvoiceDAO invoiceDAO;

	/**
	 * DAO injected by Spring that manages Item entities
	 * 
	 */
	@Autowired
	private ItemDAO itemDAO;

	/**
	 * Instantiates a new InvoiceServiceImpl.
	 *
	 */
	public InvoiceServiceImpl() {
	}

	/**
	 */
	@Transactional
	public Invoice findInvoiceByPrimaryKey(Integer id) {
		return invoiceDAO.findInvoiceByPrimaryKey(id);
	}

	/**
	 * Delete an existing Customer entity
	 * 
	 */
	@Transactional
	public Invoice deleteInvoiceCustomer(Integer invoice_id, Integer related_customer_id) {
		Invoice invoice = invoiceDAO.findInvoiceByPrimaryKey(invoice_id, -1, -1);
		Customer related_customer = customerDAO.findCustomerByPrimaryKey(related_customer_id, -1, -1);

		invoice.setCustomer(null);
		related_customer.getInvoices().remove(invoice);
		invoice = invoiceDAO.store(invoice);
		invoiceDAO.flush();

		related_customer = customerDAO.store(related_customer);
		customerDAO.flush();

		customerDAO.remove(related_customer);
		customerDAO.flush();

		return invoice;
	}

	/**
	 * Return a count of all Invoice entity
	 * 
	 */
	@Transactional
	public Integer countInvoices() {
		return ((Long) invoiceDAO.createQuerySingleResult("select count(o) from Invoice o").getSingleResult()).intValue();
	}

	/**
	 * Return all Invoice entity
	 * 
	 */
	@Transactional
	public List<Invoice> findAllInvoices(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<Invoice>(invoiceDAO.findAllInvoices(startResult, maxRows));
	}

	/**
	 * Save an existing Customer entity
	 * 
	 */
	@Transactional
	public Invoice saveInvoiceCustomer(Integer id, Customer related_customer) {
		Invoice invoice = invoiceDAO.findInvoiceByPrimaryKey(id, -1, -1);
		Customer existingcustomer = customerDAO.findCustomerByPrimaryKey(related_customer.getId());

		// copy into the existing record to preserve existing relationships
		if (existingcustomer != null) {
			existingcustomer.setId(related_customer.getId());
			existingcustomer.setEmail(related_customer.getEmail());
			existingcustomer.setFirstName(related_customer.getFirstName());
			existingcustomer.setLastName(related_customer.getLastName());
			existingcustomer.setBirthday(related_customer.getBirthday());
			existingcustomer.setAddress(related_customer.getAddress());
			existingcustomer.setCity(related_customer.getCity());
			existingcustomer.setCreatedBy(related_customer.getCreatedBy());
			existingcustomer.setCreatedOn(related_customer.getCreatedOn());
			existingcustomer.setModifiedBy(related_customer.getModifiedBy());
			existingcustomer.setModifiedOn(related_customer.getModifiedOn());
			related_customer = existingcustomer;
		} else {
			related_customer = customerDAO.store(related_customer);
			customerDAO.flush();
		}

		invoice.setCustomer(related_customer);
		related_customer.getInvoices().add(invoice);
		invoice = invoiceDAO.store(invoice);
		invoiceDAO.flush();

		related_customer = customerDAO.store(related_customer);
		customerDAO.flush();

		return invoice;
	}

	/**
	 * Load an existing Invoice entity
	 * 
	 */
	@Transactional
	public Set<Invoice> loadInvoices() {
		return invoiceDAO.findAllInvoices();
	}

	/**
	 * Delete an existing Invoice entity
	 * 
	 */
	@Transactional
	public void deleteInvoice(Invoice invoice) {
		invoiceDAO.remove(invoice);
		invoiceDAO.flush();
	}

	/**
	 * Save an existing Invoice entity
	 * 
	 */
	@Transactional
	public void saveInvoice(Invoice invoice) {
		Invoice existingInvoice = invoiceDAO.findInvoiceByPrimaryKey(invoice.getId());

		if (existingInvoice != null) {
			if (existingInvoice != invoice) {
				existingInvoice.setId(invoice.getId());
				existingInvoice.setDocument(invoice.getDocument());
				existingInvoice.setTotal(invoice.getTotal());
				existingInvoice.setCreatedBy(invoice.getCreatedBy());
				existingInvoice.setCreatedOn(invoice.getCreatedOn());
				existingInvoice.setModifiedBy(invoice.getModifiedBy());
				existingInvoice.setModifiedOn(invoice.getModifiedOn());
			}
			invoice = invoiceDAO.store(existingInvoice);
		} else {
			invoice = invoiceDAO.store(invoice);
		}
		invoiceDAO.flush();
	}

	/**
	 * Save an existing Item entity
	 * 
	 */
	@Transactional
	public Invoice saveInvoiceItems(Integer id, Item related_items) {
		Invoice invoice = invoiceDAO.findInvoiceByPrimaryKey(id, -1, -1);
		Item existingitems = itemDAO.findItemByPrimaryKey(related_items.getId());

		// copy into the existing record to preserve existing relationships
		if (existingitems != null) {
			existingitems.setId(related_items.getId());
			existingitems.setQuantity(related_items.getQuantity());
			existingitems.setCost(related_items.getCost());
			existingitems.setCreatedBy(related_items.getCreatedBy());
			existingitems.setCreatedOn(related_items.getCreatedOn());
			existingitems.setModifiedBy(related_items.getModifiedBy());
			existingitems.setModifiedOn(related_items.getModifiedOn());
			related_items = existingitems;
		}

		related_items.setInvoice(invoice);
		invoice.getItems().add(related_items);
		related_items = itemDAO.store(related_items);
		itemDAO.flush();

		invoice = invoiceDAO.store(invoice);
		invoiceDAO.flush();

		return invoice;
	}

	/**
	 * Delete an existing Item entity
	 * 
	 */
	@Transactional
	public Invoice deleteInvoiceItems(Integer invoice_id, Integer related_items_id) {
		Item related_items = itemDAO.findItemByPrimaryKey(related_items_id, -1, -1);

		Invoice invoice = invoiceDAO.findInvoiceByPrimaryKey(invoice_id, -1, -1);

		related_items.setInvoice(null);
		invoice.getItems().remove(related_items);

		itemDAO.remove(related_items);
		itemDAO.flush();

		return invoice;
	}
	
	public List<Invoice> findAllInvoices(Invoice invoice, Integer startResult, Integer maxRows){
		return invoiceDAO.findAllInvoices(invoice, startResult, maxRows);
	}
	
	public List<Invoice> findAllInvoicesForCustomer(Customer customer, int startResult, int maxRows){
		return invoiceDAO.findAllInvoicesForCustomer(customer, startResult, maxRows);
	}
}
